package org.fujene.diskblock.blockwise;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;

import javassist.NotFoundException;

import org.fujene.constants.Constants;
import org.fujene.diskblock.DiskBlock;
import org.fujene.memoryblock.MemoryBlock;
import org.fujene.memoryblock.blockwise.BlockwiseInvertIndexBlock;
import org.fujene.structure.InvertIndexData;
import org.fujene.structure.LookupPointer;
import org.fujene.toolbox.ByteConverter;

/**
 * InvertIndexBlockのサブセットとして機能します。 相対ポインタに対応しています。
 */
public class BlockwiseInvertIndexDiskBlock extends DiskBlock{
	public BlockwiseInvertIndexDiskBlock(File fileDesc) throws NotFoundException{
		super(fileDesc);
	}

	public BlockwiseInvertIndexDiskBlock(int ID, File fileDesc, int defaultBodySize, int defaultOptionSize){
		super(ID, fileDesc, Constants.MEMORY_TYPE_INVINDEX, defaultBodySize, defaultOptionSize);
	}

	public BlockwiseInvertIndexDiskBlock(BlockwiseInvertIndexBlock memBlock, String dir){
		super(memBlock, dir);
	}

	// 相対ポインタ対応
	public InvertIndexData getInvertIndex(int ptr){
		LookupPointer prevPtr, contentPtr;

		prevPtr = LookupPointer.fromBytesShort(getBody(ptr, RELPTR));
		if(prevPtr.equals(LookupPointer.EMPTY_RELATIVE))
			prevPtr = null;
		else
			prevPtr.block += this.getID();

		ptr += RELPTR;

		contentPtr = LookupPointer.fromBytesShort(getBody(ptr, RELPTR));
		if(contentPtr.equals(LookupPointer.EMPTY_RELATIVE))
			contentPtr = null;
		else
			contentPtr.block += this.getID();
		ptr += RELPTR;

		contentPtr.termfreq = ByteConverter.byteToInt(getBody(ptr, TERMFREQ));

		return new InvertIndexData(prevPtr, contentPtr, contentPtr.termfreq);
	}

	@Override
	public int toMemory(MemoryBlock memBlock){
		if(memBlock instanceof BlockwiseInvertIndexBlock){
			try{
				memBlock.setOption(0, this.getOption(0));
				memBlock.setBody(this.getBody(0, this.bodySize), 0);
				memBlock.setBodyVacancy(this.bodyVacancy);
			}catch (Exception e){}
		}
		return this.bodySize - this.bodyVacancy;
	}

	@Override
	public byte[] getData(){
		ByteArrayOutputStream stream = new ByteArrayOutputStream(this.bodySize + 4);

		try{
			stream.write(ByteConverter.intToByte(this.getOption(0), 4));
			stream.write(this.getBody(0, this.bodySize));
		}catch (IOException e){}

		return stream.toByteArray();
	}
}
